package com.hethongviet.preventing.page;

import java.util.List;
import java.util.Timer;
import java.util.TimerTask;

import com.hethongviet.preventingmachine.AppMain;
import com.hethongviet.preventingmachine.Config;
import com.hethongviet.preventingmachine.Constants;
import com.hethongviet.preventingmachine.R;

import android.os.Bundle;
import android.text.TextUtils;
import android.view.View;
import android.view.View.OnClickListener;
import android.widget.Button;
import android.widget.EditText;
import android.widget.Toast;
import android.app.Activity;
import android.app.Dialog;
import android.content.Intent;

import com.hethongviet.preventingmachine.Utils;
import com.hethongviet.preventingmachine.helps.OnSMSMessageFailListener;
import com.hethongviet.preventingmachine.helps.OnSMSMessageListener;
import com.hethongviet.preventingmachine.helps.SMSHelper;
import com.hethongviet.preventingmachine.helps.SmsReceiverDefault;
import com.hethongviet.preventingmachine.models.Account;
import com.hethongviet.preventingmachine.models.Device;
import com.hethongviet.preventingmachine.models.Number;
import com.hethongviet.preventingmachine.models.Relay;
import com.hethongviet.preventingmachine.models.SMS;
import com.hethongviet.preventingmachine.models.Sensor;
import com.hethongviet.preventingmachine.models.Transaction;
import com.hethongviet.preventingmachine.helps.dialog.DialogMessageBack;
import com.hethongviet.preventingmachine.helps.db.AccountSQLite;
import com.hethongviet.preventingmachine.helps.db.DeviceSQLite;
import com.hethongviet.preventingmachine.helps.db.NumberSQLite;
import com.hethongviet.preventingmachine.helps.db.RelaySQLite;
import com.hethongviet.preventingmachine.helps.db.SensorSQLite;

public class PageLoginActivity extends Activity implements
		OnSMSMessageListener, OnSMSMessageFailListener
{
	private DeviceSQLite _DeviceSQLite = null;
	private AccountSQLite _AccountSQLite = null;
	private SensorSQLite _SensorSQLite = null;
	private RelaySQLite _RelaySQLite = null;
	private NumberSQLite _NumberSQLite = null;

	private Account _Account = null;
	private Device _Device = null;

	private EditText _EditTextDeviceNumber = null;
	private EditText _EditTextPassword = null;

	private Button _ButtonLogin = null;
	private Button _ButtonLoginAsUser = null;

	private Timer _TimerOutSMS = null;

	@Override
	public void onCreate(Bundle savedInstanceState)
	{
		super.onCreate(savedInstanceState);

		Utils.prepareWindow(this);

		setContentView(R.layout.page_login);

		_EditTextDeviceNumber = (EditText) findViewById(R.id.login_text_device_number);
		_EditTextPassword = (EditText) findViewById(R.id.login_text_password);

		_ButtonLogin = (Button) findViewById(R.id.login_button_login);
		_ButtonLoginAsUser = (Button) findViewById(com.hethongviet.preventer.admin.R.id.login_button_user);

		initDB();

		initListRelays();
		initListSensors();

		_Device = _DeviceSQLite.getAll().get(0);
		_Account = _AccountSQLite.getAll().get(0);

		if (_Account == null || _Device == null)
		{
			Utils.debug("Error loading database!!!");
			finish();
			return;
		}
		
		if(TextUtils.isEmpty(_Device.getName()))
		{
			_Device.setName("VSYS");
		}

		_EditTextPassword.setText(_Account.getPassword());
		_EditTextDeviceNumber.setText(_Device.getNumber());

		SMSHelper.setDeviceNumber(_Device.getNumber());

		_ButtonLogin.setOnClickListener(new OnClickListener()
		{

			@Override
			public void onClick(View arg0)
			{
				String password = _EditTextPassword.getText().toString();

				if (password == null || password.equals(""))
				{
					try
					{
						showDialog(R.string.message_error_login_must_input_password);
					} catch (Exception e)
					{
						e.printStackTrace();
					}

					return;
				}
				for (int index = 0; index < password.length(); index++)
				{
					char c = password.charAt(index);

					if (!Character.isLetterOrDigit(c))
					{
						showDialogWithCatch(R.string.message_error_wrong_input_password);
						return;
					}
				}

				if (password.length() < Constants.LENGTH_MIN_PASSWORD)
				{
					showDialogWithCatch(R.string.message_error_input_too_short_password);
					return;
				}

				if (password.length() > Constants.LENGTH_MAX_PASSWORD)
				{
					showDialogWithCatch(R.string.message_error_input_too_long_password);
					return;
				}

				String number = _EditTextDeviceNumber.getText().toString();

				if (number == null || number.equals(""))
				{
					try
					{
						showDialog(R.string.message_error_login_must_input_number);
					} catch (Exception e)
					{
						e.printStackTrace();
					}
					return;
				}

				if (number.length() < Constants.LENGTH_MIN_NUMBER)
				{
					showDialogWithCatch(R.string.message_error_input_too_short_number);
					return;
				}

				if (number.length() > Constants.LENGTH_MAX_NUMBER)
				{
					showDialogWithCatch(R.string.message_error_input_too_long_number);
					return;
				}

				for (int index = 0; index < number.length(); index++)
				{
					char c = number.charAt(index);

					if (!Character.isDigit(c) && c != '+')
					{
						showDialogWithCatch(R.string.message_error_wrong_input_number);
						return;
					}
				}

				Utils.debug("SMSHelper.setDeviceNumber: " + number);
				_Device.setNumber(number);
				_DeviceSQLite.insert(_Device);
				SMSHelper.setDeviceNumber(number);

				_Account.setPassword(password);
				_AccountSQLite.insert(_Account);

				// if (_Account.getPassword().equals(password))
				{
					/* Set SMS pin */
					SMSHelper.setPassword(password);

					if (Config.IS_SMS_UPDATE_ALL)
					{
						/* Update all */
						Utils.showProgress(PageLoginActivity.this);
						_TimerOutSMS = new Timer();
						TimerTask task = new TimerTask()
						{

							@Override
							public void run()
							{
								Utils.hideProgressDialog();
								onSMSMessageFail(null,
										R.string.message_fail_update_all);
							}
						};

						_TimerOutSMS.schedule(task, 4 * Constants.TIME_OUT_SMS);

						SMSHelper.updateAll();

						debugSendSMS(SMSHelper.DEBUG_SMS_UPDATE_ALL_1);
						debugSendSMS(SMSHelper.DEBUG_SMS_UPDATE_ALL_2);
						debugSendSMS(SMSHelper.DEBUG_SMS_UPDATE_ALL_3);
						debugSendSMS(SMSHelper.DEBUG_SMS_UPDATE_ALL_4);
					}
					else
					{
						Utils.debug("Login successful!!!!!!");
						Intent intent = new Intent(PageLoginActivity.this,
								PageAdminActivity.class);
						startActivity(intent);
						_CountUpdateAll = 0;
						Utils.hideProgressDialog();
					}
				}

				// else
				// {
				// Utils.debug("Error: Login unsuccessful!!!!!!");
				// try
				// {
				// showDialog(R.string.message_error_login_fail);
				// } catch (Exception e)
				// {
				// e.printStackTrace();
				// }
				//
				// }
			}
		});
		
		_ButtonLoginAsUser.setOnClickListener(new OnClickListener()
		{
			
			@Override
			public void onClick(View arg0)
			{
				finish();
			}
		});
	}

	@Override
	protected void onResume()
	{

		SmsReceiverDefault.setOnSMSMessageListener(this);
		SMSHelper.setActivity(this);
		SMSHelper.setMessageId(0);

		super.onResume();
	}

	private void showDialogWithCatch(int id)
	{
		try
		{
			showDialog(id);
		} catch (Exception e)
		{
			e.printStackTrace();
		}
	}

	private void initDB()
	{
		_SensorSQLite = new SensorSQLite(this, AppMain.getInstance()
				.getDBName());
		_RelaySQLite = new RelaySQLite(this, AppMain.getInstance().getDBName());
		_AccountSQLite = new AccountSQLite(this, AppMain.getInstance()
				.getDBName());
		_DeviceSQLite = new DeviceSQLite(this, AppMain.getInstance()
				.getDBName());
		_NumberSQLite = new NumberSQLite(this, AppMain.getInstance()
				.getDBName());
	}

	private void initListSensors()
	{
		_SensorSQLite.deleteAll();
		for (int index = 0; index < Constants.MAX_SENSORS; index++)
		{
			Sensor sensor = new Sensor();
			sensor.setIndex(index);
			sensor.setName("Sensor " + (index + 1));

			_SensorSQLite.insert(sensor);
		}

	}

	private void initListRelays()
	{
		_RelaySQLite.deleteAll();
		for (int index = 0; index < Constants.MAX_RELAYS; index++)
		{
			Relay relay = new Relay();
			relay.setIndex(index);
			relay.setName("Relay " + (index + 1));
			relay.setOn(index % 2 == 0);

			_RelaySQLite.insert(relay);
		}
	}

	@Override
	protected Dialog onCreateDialog(int id)
	{
		if (id == R.string.message_error_input_too_long_number)
		{
			return new DialogMessageBack(this, true, String.format(
					getString(id), Constants.LENGTH_MAX_NUMBER), false);
		}
		else if (id == R.string.message_error_input_too_short_number)
		{
			return new DialogMessageBack(this, true, String.format(
					getString(id), Constants.LENGTH_MIN_NUMBER), false);
		}
		else if (id == R.string.message_error_input_too_long_password)
		{
			return new DialogMessageBack(this, true, String.format(
					getString(id), Constants.LENGTH_MAX_PASSWORD), false);
		}
		else if (id == R.string.message_error_input_too_short_password)
		{
			return new DialogMessageBack(this, true, String.format(
					getString(id), Constants.LENGTH_MIN_PASSWORD), false);
		}
		else
			return new DialogMessageBack(this, true, id, false);
	}

	private int _CountUpdateAll = 0;

	@Override
	public void onSMSMessageIncoming(SMS sms)
	{

		Utils.debug("Message receive = " + sms.getMessage());
		String message = Utils.prepareMessage(sms.getMessage());

		Utils.debug("Message receive valid = " + message);

		if (message == null || message.equals(""))
		{
			Utils.debug("ERROR----- wrong message! NULL");
			return;
		}

		if (message.contains(SMSHelper.CODE_ERROR_UPDATE + ""))
		{
			Utils.hideProgressDialog();

			showDialogWithCatch(R.string.message_error_login_wrong_password);
			_CountUpdateAll = 0;

			if (_TimerOutSMS != null)
			{
				_TimerOutSMS.cancel();
				_TimerOutSMS = null;
			}
			return;
		}

		if (message.length() <= SMSHelper.CODE_UPDATE_ALL.length() + 1)
		{
			Utils.debug("ERROR----- wrong message!");
			return;
		}

		String codeSMS = message.substring(0,
				SMSHelper.CODE_UPDATE_ALL.length() + 1);
		Utils.debug("codeSMS = " + codeSMS);

		if (!codeSMS.equals(SMSHelper.CODE_RESPONSE_UPDATE_ALL_PHONE_ALARM)
				&& !codeSMS
						.equals(SMSHelper.CODE_RESPONSE_UPDATE_ALL_PHONE_CONTROL)
				&& !codeSMS.equals(SMSHelper.CODE_RESPONSE_UPDATE_ALL_RELAY)
				&& !codeSMS.equals(SMSHelper.CODE_RESPONSE_UPDATE_ALL_SENSOR))
		{
			Utils.debug("ERROR----- wrong message!");
			return;
		}

		String insideMessage = null;
		try
		{
			insideMessage = message.substring(
					SMSHelper.CODE_UPDATE_ALL.length() + 2,
					message.length() - 8);

		} catch (Exception e)
		{
			e.printStackTrace();
			return;
		}

		if (insideMessage == null || insideMessage.equals(""))
		{
			Utils.debug("ERROR----- wrong message!Null content");
			return;
		}

		Utils.debug("insideMessage = " + insideMessage);

		if (codeSMS.equals(SMSHelper.CODE_RESPONSE_UPDATE_ALL_PHONE_ALARM))
		{
			_CountUpdateAll++;

			String[] numbers = insideMessage.split("[)(]+");

			if (numbers == null || numbers.length == 0)
			{
				Utils.debug("ERROR----- no alarm number!");
				return;
			}

			Utils.debug("Names size = " + numbers.length);

			List<Number> numbersList = _NumberSQLite.getAll();

			for (int indexName = 0; indexName < numbers.length; indexName++)
			{
				String numberString = numbers[indexName];
				if (numberString == null
						|| numberString.equals("")
						|| numberString.charAt(0) == SMSHelper.CODE_REPLACE_NULL)
				{
					continue;
				}

				Number numberInsert = new Number();
				numberInsert.setNumber(numberString);
				numberInsert.setAlarm(true);
				numberInsert.setActive(true);

				if (numbersList != null)
				{
					for (Number number : numbersList)
					{
						if (number.getNumber().equals(numberString))
						{
							numberInsert = number;
							break;
						}
					}
				}

				_NumberSQLite.insert(numberInsert);
			}

		}
		else if (codeSMS
				.equals(SMSHelper.CODE_RESPONSE_UPDATE_ALL_PHONE_CONTROL))
		{
			_CountUpdateAll++;

			String[] numbers = insideMessage.split("[)(]+");

			if (numbers == null || numbers.length == 0)
			{
				Utils.debug("ERROR----- no control number!");
				return;
			}
			Utils.debug("Names size = " + numbers.length);

			List<Number> numbersList = _NumberSQLite.getAll();

			for (int indexName = 0; indexName < numbers.length; indexName++)
			{
				String numberString = numbers[indexName];
				if (numberString == null
						|| numberString.equals("")
						|| numberString.charAt(0) == SMSHelper.CODE_REPLACE_NULL)
				{
					continue;
				}

				Number numberInsert = new Number();
				numberInsert.setNumber(numberString);
				numberInsert.setControl(true);
				numberInsert.setActive(true);

				if (numbersList != null)
				{
					for (Number number : numbersList)
					{
						if (number.getNumber().equals(numberString))
						{
							numberInsert = number;
							break;
						}
					}
				}

				_NumberSQLite.insert(numberInsert);
			}

		}

		else if (codeSMS.equals(SMSHelper.CODE_RESPONSE_UPDATE_ALL_RELAY))
		{
			_CountUpdateAll++;

			final int INDEX_RELAY_NAMES = 0;
			final int INDEX_RELAY_STATUS = INDEX_RELAY_NAMES + 1;
			final int INDEX_DEVICE_NAME = INDEX_RELAY_STATUS + 1;
			@SuppressWarnings("unused")
			final int INDEX_DEVICE_TEMPERATURE = INDEX_DEVICE_NAME + 1;

			String[] strings = insideMessage.split("[-]");

			if (strings == null || strings.length == 0)
			{
				Utils.debug("ERROR--- no thing!");
				return;
			}

			String status = strings[INDEX_RELAY_STATUS].substring(1,
					strings[INDEX_RELAY_STATUS].length() - 1);
			Utils.debug("status = " + status);

			_Device.setName(strings[INDEX_DEVICE_NAME].substring(1,
					strings[INDEX_DEVICE_NAME].length() - 1));
			_DeviceSQLite.insert(_Device);

			/* Names */
			String relayNames = strings[INDEX_RELAY_NAMES].substring(0,
					strings[INDEX_RELAY_NAMES].length() - 1);
			String[] names = relayNames.split("[)(]+");

			if (names == null || names.length == 0)
			{
				Utils.debug("ERROR--- no relay!");
				return;
			}

			Utils.debug("Names size = " + names.length);

			List<Relay> relayList = _RelaySQLite.getAll();

			for (int indexName = 0; indexName < names.length; indexName++)
			{
				String name = names[indexName];
				if (name != null && !name.equals("")
						&& name.charAt(0) != SMSHelper.CODE_REPLACE_NULL)
				{
					relayList.get(indexName).setName(names[indexName]);
				}

				char c = status.charAt(indexName);
				if (c == '0')
				{
					relayList.get(indexName).setOn(false);
				}
				else
				{
					relayList.get(indexName).setOn(true);
				}

				_RelaySQLite.insert(relayList.get(indexName));

			}
		}

		else if (codeSMS.equals(SMSHelper.CODE_RESPONSE_UPDATE_ALL_SENSOR))
		{
			_CountUpdateAll++;

			String[] names = insideMessage.split("[)(]+");

			if (names == null || names.length == 0)
			{
				Utils.debug("ERROR--- no sensor!");
				return;
			}

			Utils.debug("Names size = " + names.length);

			List<Sensor> sensorList = _SensorSQLite.getAll();

			for (int indexName = 0; indexName < names.length; indexName++)
			{
				String name = names[indexName];
				if (name != null && !name.equals("")
						&& name.charAt(0) != SMSHelper.CODE_REPLACE_NULL)
				{
					sensorList.get(indexName).setName(names[indexName]);

					_SensorSQLite.insert(sensorList.get(indexName));
				}

			}
		}

		if (_CountUpdateAll == 4)
		{
			if (_TimerOutSMS != null)
			{
				_TimerOutSMS.cancel();
				_TimerOutSMS = null;
			}

			Utils.debug("Login successful!!!!!!");
			Intent intent = new Intent(PageLoginActivity.this,
					PageAdminActivity.class);
			startActivity(intent);
			_CountUpdateAll = 0;
			Utils.hideProgressDialog();
		}
	}

	private void debugSendSMS(final String message)
	{
		final SMS sms = new SMS();
		sms.setRecipient(SMSHelper.getDeviceNumber());
		sms.setMessage(message);

		if (Config.IS_DEBUG_SMS_RECEIVE)
		{
			new Thread(new Runnable()
			{

				@Override
				public void run()
				{
					try
					{
						Thread.sleep(Constants.TIME_DEBUG_SEND_SMS);
					} catch (Exception e)
					{
						e.printStackTrace();
					}
					PageLoginActivity.this.runOnUiThread(new Runnable()
					{

						@Override
						public void run()
						{
							onSMSMessageIncoming(sms);
						}
					});
				}
			}).start();

		}
	}

	@Override
	public void onSMSMessageFail(final Transaction transaction,
			final int messageFailId)
	{
		runOnUiThread(new Runnable()
		{

			@Override
			public void run()
			{
				if (messageFailId > 0)
					Toast.makeText(PageLoginActivity.this, messageFailId,
							Toast.LENGTH_LONG).show();

				switch (messageFailId)
				{
					case R.string.message_fail_update_all:
						showDialogWithCatch(messageFailId);
						break;
					default:
						break;
				}
			}
		});

	}
}
